from fastapi import FastAPI, Query
from fastapi.middleware.cors import CORSMiddleware
from views.auth import router as auth_router
from views.posts import router as posts_router
from views.real_name_auth import router as real_name_auth_router
from views.customer_service import router as customer_service_router

from database import init_db
from config import settings

# 初始化FastAPI应用
app = FastAPI(title="Reddbook API", version="1.0.0")

# 配置CORS - 允许前端域名访问
app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        settings.FRONTEND_URL,
        "http://localhost:5173",
        "http://127.0.0.1:5173",
    ],  # 前端URL
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH"],
    allow_headers=["*"],
    expose_headers=["*"],
)

# 注册路由
app.include_router(auth_router, prefix="/api", tags=["auth"])
app.include_router(posts_router, tags=["posts"])
app.include_router(real_name_auth_router, prefix="/api/real-name-auth", tags=["real-name-auth"])
app.include_router(customer_service_router, tags=["customer-service"])



@app.get("/")
async def root():
    return {"message": "Welcome to Reddbook API"}


@app.get("/demo/factory")
async def demo_factory():
    """工厂模式演示接口"""
    from tools.factory import NotificationFactory
    
    # 演示工厂模式：根据类型创建不同的通知处理器
    handlers = []
    for handler_type in ['email', 'sms', 'push']:
        handler = NotificationFactory.create_handler(handler_type)
        handlers.append(handler_type)
    
    return {
        "message": "工厂模式演示",
        "说明": "工厂模式可以根据类型创建不同的对象",
        "已创建的处理器": handlers,
        "使用方式": "NotificationFactory.create_handler('email')"
    }


@app.post("/demo/observer")
async def demo_observer(
    event_type: str = Query(..., description="事件类型 ('like', 'view', 'comment')"),
    post_id: int = Query(1, description="帖子ID"),
    user_id: int = Query(None, description="用户ID（可选）")
):
    """
    观察者模式演示接口
    
    参数:
        event_type: 事件类型 ('like', 'view', 'comment')
        post_id: 帖子ID（默认1）
        user_id: 用户ID（可选）
    """
    from tools.observer import post_observer, PostEvent
    import io
    from contextlib import redirect_stdout
    
    # 捕获观察者的输出
    f = io.StringIO()
    with redirect_stdout(f):
        event = PostEvent(event_type=event_type, post_id=post_id, user_id=user_id)
        post_observer.notify(event)
    
    # 获取输出内容
    output = f.getvalue().strip().split('\n')
    
    return {
        "message": "观察者模式演示",
        "event_type": event_type,
        "post_id": post_id,
        "observers_executed": len(output),
        "logs": output
    }


@app.on_event("startup")
async def startup_event():
    """应用启动时初始化数据库和定时任务"""
    try:
        # 初始化数据库，创建表结构（如果表不存在的话）
        # init_db()是同步函数，直接调用即可
        init_db()
        print("[启动] 数据库初始化完成")
    except Exception as e:
        # 如果数据库初始化失败，打印错误但不中断启动
        print(f"[启动警告] 数据库初始化失败: {e}")
    
    try:
        # 启动定时任务调度器
        # 调度器会每5秒检查一次队列，如果有任务就处理
        # 注意：start_scheduler现在是异步函数，需要用await等待
        from tools.scheduler import start_scheduler
        await start_scheduler()
    except Exception as e:
        # 如果调度器启动失败，打印错误但不中断启动
        # 这样即使Redis没有启动，应用也能正常运行
        print(f"[启动警告] 定时任务调度器启动失败: {e}")
        print("[启动提示] 应用仍可运行，但队列处理功能不可用，请检查Redis是否启动")


@app.on_event("shutdown")
async def shutdown_event():
    """应用关闭时停止定时任务"""
    # 关闭定时任务调度器
    # 确保在应用关闭时，定时任务也能正确停止
    # 注意：shutdown_scheduler现在是异步函数，需要用await等待
    from tools.scheduler import shutdown_scheduler
    await shutdown_scheduler()